package cn.hiapi.core.basic.redis.service;

import cn.hiapi.core.basic.redis.ILockService;
import cn.hiapi.core.basic.exception.LockException;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;

/**
 * @author AdinZ
 * @date 2020/11/7 14:12
 */
public interface RedisService extends ILockService {

    RedisTemplate getRedisTemplate();


    <K> void rename(K oldName, K newName);

    /**
     * 获取 redis  K/V
     *
     * @return
     */
    <K, V> V get(K key);

    /**
     * 获取 redis Map
     *
     * @return
     */
    <H, HK, HV> HV get(H h, HK hk);

    /**
     * 获取 redis List
     *
     * @return
     */
    <K, V> List<V> get(K k, long start, long end);

    /**
     * redis 查询key值 通配符 *
     *
     * @return
     */
    <K> Set<K> keys(K key);

    /**
     * 添加redis K/V
     */
    <K, V> void set(K k, V v);

    /**
     * 添加 redis K/V 包含过期时间 毫秒
     */
    <K, V> void set(K k, V v, long expire);

    /**
     * 添加redis  Map
     */
    <H, HK, HV> void set(H h, HK hk, HV hv);

    <H, HK, HV> void setMap(H h, HK hk, HV hv);

    /**
     * 添加redis  Map
     */
    <H, HK, HV> void set(H h, Map<HK, HV> map);

    /**
     * 添加redis List
     */
    <K, V> void set(K k, Collection<V> v);

    /**
     * 删除redis
     *
     * @param k
     * @param <K>
     */
    <K> void delete(K k);

    <K> void delete(Collection<K> keys);

    /**
     * 删除redis Map
     */
    <H, HK> void delete(H h, HK... hk);

    <H, HK, HV> Map<HK, HV> getMap(H h);

    <H, HV> List<HV> getMapValue(H h);

    <H, HK> Set<HK> getMapKeys(H h);

    <K> long increment(K key, long index);

    <K> double increment(K key, double index);

    <H, HK> long increment(H h, HK hk, long index);

    <H, HK> double increment(H h, HK hk, double index);



    <K> void expire(K k, long expire);


    default <K> void lockThr(K k) {
        if (!this.lock(k)) {
            throw new LockException(700, "锁ID :" + k);
        }
    }

    default <K> void lockThr(K k, long timeout) {
        if (!this.lock(k, timeout)) {
            throw new LockException(700, "锁ID :" + k);
        }
    }


    IList list();

    IMap map();

    IGeo geo();

    interface IList {


        <K, V> ListOperations<K, V> operations();
        <K, V> List<V> get(K k, long start, long end);

        <K, V> List<V> get(K k, long end);

        <K, V> V getRemove(K k);

        <K, V> V getRemove(K k, long timeout);


        <K, V> Long add(K k, Collection<V> v);

        <K, V> Long addTop(K k, Collection<V> v);


        <K> long size(K k);

        <K> void trim(K k, long start, long end);


        default <K, V> Long add(K k, V v) {
            return this.add(k, Collections.singletonList(v));
        }

        default <K, V> Long addTop(K k, V v) {
            return this.addTop(k, Collections.singletonList(v));
        }

    }

    interface IMap {
        <K, HK, HV> HashOperations<K, HK, HV> operations();

        <K, HK, HV> void putAll(K key, Map<? extends HK, ? extends HV> m);

    }

    interface IGeo{

    }

}
